package com.spring.reader;


import com.spring.annotation.Configuration;
import com.spring.bean.BeanDefinition;
import com.spring.context.BeanDefinitionRegistry;
import com.spring.enums.ScopeType;
import com.spring.beanpostprocessor.ConfigurationClassPostProcessor;
import com.spring.util.StringUtils;

/**
 * 用来读取被 作为参数传入进来的 配置类.class 信息,  只管注册 配置类 的beanDefinition 信息，不管解析的！！
 */
public class AnnotationBeanDefinitionReader {
	/**
	 * reader 不负责保存bean定义，这个事情委托给 注册器 处理
	 */
	private final BeanDefinitionRegistry registry;
	
	/**
	 * Configuration类的bean定义后置处理器
	 */
	private final ConfigurationClassPostProcessor configurationClassPostProcessor;
	
	public AnnotationBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this.registry = registry;
		this.configurationClassPostProcessor = new ConfigurationClassPostProcessor(registry);
	}
	
	
	/**
	 * 注册类定义
	 *
	 * @param annotationClasses 配置类class
	 */
	public void register(Class<?>... annotationClasses) {
		if (annotationClasses == null || annotationClasses.length == 0) {
			return;
		}
		
		for (Class<?> annotationClass : annotationClasses) {
			// 如果传入的 .class 上有 @Configuration 注解才进行解析,没有这个注解就直接跳过
			if (annotationClass.isAnnotationPresent(Configuration.class)) {
				registerBean(annotationClass);
			}
		}
		// 调用真正的解析器去扫描遍历加载一下
		configurationClassPostProcessor.postProcessBeanDefinitionRegistry(registry);
	}
	
	private void registerBean(Class<?> annotationClass) {
		doRegisterBean(annotationClass);
	}
	
	
	/**
	 * 把 配置类 自身的 定义注册一下
	 *
	 * @param annotationClass 配置类
	 */
	private void doRegisterBean(Class<?> annotationClass) {
		// 得到类名简写 ，首字母小写后作为bean名字
		String beanName = StringUtils.toLowerFirstCase(annotationClass.getSimpleName());
		
		// 配置类一律单例
		BeanDefinition bd = new BeanDefinition();
		bd.setBeanName(beanName);
		bd.setBeanClass(annotationClass);
		bd.setScope(ScopeType.SINGLE);
		
		// 配置类自身也作为一个普通bean定义信息放入进去
		// 注册的事情委托给注册器
		registry.registryBeanDefinition(beanName, bd);
	}
}
